


#ifndef _MTRAP_H
#define _MTRAP_H

#include "types.h"
#include "functions.h"


#ifndef __GNUC_VA_LIST
#define __GNUC_VA_LIST
typedef __builtin_va_list __gnuc_va_list;
#endif

#ifndef __va_list__
typedef __gnuc_va_list va_list;
#endif /* not __va_list__ */


#define va_start(v,l)	__builtin_va_start(v,l)
#define va_end(v)	__builtin_va_end(v)

void poweroff(uint16 code) __attribute((noreturn));
void printm(const char* s, ...);
void putstring(const char* s);
#define assert(x) ({ if (!(x)) die("assertion failed: %s", #x); })
#define die(str, ...) ({ printm("%s:%d: " str "\n", __FILE__, __LINE__, ##__VA_ARGS__); poweroff(-1); })


typedef struct {
  volatile uint32* ipi;
  volatile int mipi_pending;

  volatile uint64* timecmp;

  volatile uint32* plic_m_thresh;
  volatile uintptr_t* plic_m_ie;
  volatile uint32* plic_s_thresh;
  volatile uintptr_t* plic_s_ie;
} hls_t;

#define HLS_SIZE 64
#define HLS() ((hls_t*)(MACHINE_STACK_TOP()))
#define OTHER_HLS(id)  ((hls_t*)(MACHINE_STACK_TOP_K(id)))

extern volatile uint64* mtime;

void hls_printm(hls_t * hls);
void hls_printk(hls_t * hls);
hls_t* hls_init(uintptr_t id);
void vPortSetupTimer(void);
#endif
